""" 
自定义异常处理器 
""" 
import traceback
import logging
from django.core.mail import send_mail
from django.conf import settings
from django.http import JsonResponse
from django.core.exceptions import ValidationError
from django.db import DatabaseError
from rest_framework.views import exception_handler 
from rest_framework.exceptions import AuthenticationFailed 
from rest_framework.response import Response 
from rest_framework import status 

def custom_exception_handler(exc, context): 
    # 调用默认的异常处理器 
    response = exception_handler(exc, context) 
    
    # 如果是认证失败异常 
    if isinstance(exc, AuthenticationFailed): 
        return Response({ 
            'status': 401, 
            'data': { 
                'msg': '登录过期，请重新登录', 
                'code': 'TOKEN_EXPIRED' 
            } 
        }, status=status.HTTP_401_UNAUTHORIZED) 
    
    # 如果是其他401错误 
    if response is not None and response.status_code == status.HTTP_401_UNAUTHORIZED: 
        return Response({ 
            'status': 401, 
            'data': { 
                'msg': '登录过期，请重新登录', 
                'code': 'TOKEN_EXPIRED' 
            } 
        }, status=status.HTTP_401_UNAUTHORIZED) 
    
    return response  # 这里修复了语法错误


# 自定义异常处理函数 发送报错的

# 配置日志 logger
logger = logging.getLogger(__name__)

class GlobalErrorHandler:
    
    @staticmethod
    def handle_exception(exception,request=None):
        """处理异常并发送邮件通知"""
        
        # 获取异常信息
        error_type = type(exception).__name__
        error_message = str(exception)
        
        # 获取详细的堆栈跟踪信息
        stack_trace = traceback.format_exc()
        
        # 记录主要错误信息
        logger.error(f"错误类型: {error_type}, 错误信息: {error_message}")
        logger.error(f"堆栈跟踪:\n{stack_trace}")
        
        # 发送邮件通知
        try:
            if hasattr(settings, 'ADMIN_EMAILS') and settings.ADMIN_EMAILS:
                subject = f"【系统错误】{error_type}"
                
                # 构建详细的邮件内容，包含堆栈跟踪
                message = f"""错误类型: {error_type}
错误信息: {error_message}

详细堆栈跟踪:
{stack_trace}

请求信息:
- URL: {request.build_absolute_uri() if request else 'N/A'}
- 方法: {request.method if request else 'N/A'}
- 用户: {request.user if request and hasattr(request, 'user') else '匿名用户'}

请检查相关代码文件中的具体行号以定位问题。"""
                
                send_mail(
                    subject=subject,
                    message=message,
                    from_email=settings.EMAIL_HOST_USER,
                    recipient_list=settings.ADMIN_EMAILS,
                    fail_silently=False
                )
                logger.info(f"错误邮件已发送至: {settings.ADMIN_EMAILS}")
            else:
                logger.warning("未配置管理员邮箱，错误邮件未发送")
        except Exception as mail_error:
            logger.error(f"发送错误邮件失败: {str(mail_error)}")

class GlobalExceptionMiddleware:
    """全局异常中间件"""
    
    def __init__(self, get_response):
        self.get_response = get_response
    
    def __call__(self, request):
        response = self.get_response(request)
        return response
    
    def process_exception(self, request, exception):
        """处理视图函数中的异常"""
        
        # 处理不同类型的异常
        if isinstance(exception, ValidationError):
            error_response = {
                'status': 400,
                'error': 'ValidationError',
                'message': '数据验证失败'
            }
            status_code = 400
            
        elif isinstance(exception, DatabaseError):
            error_response = {
                'status': 500,
                'error': 'DatabaseError',
                'message': '数据库操作失败，请稍后重试'
            }
            status_code = 500
            
        elif isinstance(exception, ValueError):
            error_response = {
                'status': 400,
                'error': 'ValueError',
                'message': f'参数错误: {str(exception)}'
            }
            status_code = 400
            
        else:
            error_response = {
                'status': 500,
                'error': type(exception).__name__,
                'message': f'服务器内部错误: {str(exception)}'
            }
            status_code = 500
        
        # 调用全局错误处理器记录日志和发送邮件
        GlobalErrorHandler.handle_exception(exception, request)
        
        # 返回JSON响应
        return JsonResponse(error_response, status=status_code)

